<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>OGNL使用总结</title>
</head>

<body>
<div class="titlepage">
  <center>
    <h2 class="title">OGNL使用总结</h2>
  </center>
  参考文献：<br />
  http://www.cnblogs.com/xly1208/archive/2011/11/19/2255500.html<br />
http://blog.csdn.net/chenjian198819/article/details/6638186</div>
<p>&nbsp;</p>
<p>1、访问属性：</p>
<table border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td valign="top"><p>&lt;s:property value=&quot;user.username&quot;/&gt;，前提：user位于s:debug的值栈(ValueStack)中。(Struts2总是把当前Action实例放置在栈顶，即ValueStack。访问值栈中的对象不用“#&rdquo;。</p>
        <p>&lt;s:property value=&quot;#user.username&quot;/&gt;，前提：user位于s:debug的栈上下文(Stack Context)中，需要用&ldquo;#&rdquo;。</p></td>
    </tr>
  </tbody>
</table>
<p>&nbsp;</p>
<p>2、访问方法：</p>
<table border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td valign="top"><p>&lt;s:property value=&quot;user.get()&quot;/&gt;，前提：user位于s:debug的值栈(ValueStack)中，且包含非私有方法get()方法。</p></td>
    </tr>
  </tbody>
</table>
<p>&nbsp;</p>
<p>3、访问静态属性和方法：</p>
<table border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td valign="top"><p>调用Action中的静态方法：&lt;s:property value=&quot;@struts.action.LoginAction@get()&quot;/&gt;</p>
        <p>调用JDK中的类的静态方法：&lt;s:property value=&quot;@java.lang.Math@floor(44.56)&quot;/&gt;，如果没有指定 class 那么默认就使用 java.lang.Math。例如：&lt;s:property value=&quot;@@floor(44.56)&quot;/&gt;。</p>
        <p>调用JDK中的类的静态方法(同上)：&lt;s:property value=&quot;@@floor(44.56)&quot;/&gt;</p>
        <p>调用JDK中的类的静态方法：&lt;s:property value=&quot;@java.util.Calendar@getInstance()&quot;/&gt;</p>
        <p>调用普通类中的静态属性：&lt;s:property value=&quot;@struts.vo.Address@TIPS&quot;/&gt;</p></td>
    </tr>
  </tbody>
</table>
<p>&nbsp;</p>
<p>4、访问构造方法：</p>
<table border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td valign="top"><p>调用普通类的构造方法:&lt;s:property value=&quot;new com.vo.User('李晓红' , '美女' , 3 , 25).username&quot;/&gt;</p></td>
    </tr>
  </tbody>
</table>
<p>&nbsp;</p>
<p>5、访问数组：List、Set、Map</p>
<table border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td width="558" valign="top"><p>获取List：&lt;s:property value=&quot;testList&quot;/&gt;</p>
        <p>获取List中的某一个元素(可以使用类似于数组中的下标获取List中的内容)：</p>
        <p>&lt;s:property value=&quot;testList[0]&quot;/&gt;</p>
        <p>获取Set：&lt;s:property value=&quot;testSet&quot;/&gt;</p>
        <p>获取Set中的某一个元素(Set由于没有顺序，所以不能使用下标获取数据)：</p>
        <p><s>&lt;s:property value=&quot;testSet[0]&quot;/&gt;</s></p>
        <p>获取Map：&lt;s:property value=&quot;testMap&quot;/&gt;</p>
        <p>获取Map中所有的键：&lt;s:property value=&quot;testMap.keys&quot;/&gt;</p>
        <p>获取Map中所有的值：&lt;s:property value=&quot;testMap.values&quot;/&gt;</p>
        <p>获取Map中的某一个元素(可以使用类似于数组中的下标获取List中的内容)：</p>
        <p>&lt;s:property value=&quot;testMap['m1']&quot;/&gt;</p>
        <p>获取List的大小：&lt;s:property value=&quot;testSet.size&quot;/&gt;</p></td>
    </tr>
  </tbody>
</table>
<p>&nbsp;</p>
<p>6、访问集合 – 投影、选择(? ^ $)：</p>
<table border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td valign="top"><p>利用选择获取List中成绩及格的对象：&lt;s:property value=&quot;stus.{?#this.grade&gt;=60}&quot;/&gt;</p>
        <p>利用选择获取List中成绩及格的对象的username：</p>
        <p>&lt;s:property value=&quot;stus.{?#this.grade&gt;=60}.{username}&quot;/&gt;</p>
        <p>利用选择获取List中成绩及格的第一个对象的username：</p>
        <p>&lt;s:property value=&quot;stus.{?#this.grade&gt;=60}.{username}[0]&quot;/&gt;</p>
        <p>利用选择获取List中成绩及格的第一个对象的username：</p>
        <p>&lt;s:property value=&quot;stus.{^#this.grade&gt;=60}.{username}&quot;/&gt;</p>
        <p>利用选择获取List中成绩及格的最后一个对象的username：</p>
        <p>&lt;s:property value=&quot;stus.{$#this.grade&gt;=60}.{username}&quot;/&gt;</p>
        <p>利用选择获取List中成绩及格的第一个对象然后求大小：</p>
        <p>&lt;s:property value=&quot;stus.{^#this.grade&gt;=600}.{username}.size&quot;/&gt;</p></td>
    </tr>
  </tbody>
</table>
<p>&nbsp;</p>
<p>7、集合的伪属性：</p>
<p>OGNL能够引用集合的一些特殊的属性，这些属性并不是JavaBeans模式，例如size(),length()等等。当表达式引用这些属性时，OGNL会调用相应的方法，这就是伪属性。</p>
<table border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td valign="top"><p>集合</p></td>
      <td valign="top"><p>伪属性</p></td>
    </tr>
    <tr>
      <td valign="top"><p>Collection(inherited by Map, List &amp; Set)</p></td>
      <td valign="top"><p>size ，isEmpty</p></td>
    </tr>
    <tr>
      <td valign="top"><p>List</p></td>
      <td valign="top"><p>iterator</p></td>
    </tr>
    <tr>
      <td valign="top"><p>Map</p></td>
      <td valign="top"><p>keys，values</p></td>
    </tr>
    <tr>
      <td valign="top"><p>Set</p></td>
      <td valign="top"><p>iterator</p></td>
    </tr>
    <tr>
      <td valign="top"><p>Iterator</p></td>
      <td valign="top"><p>next，hasNext</p></td>
    </tr>
    <tr>
      <td valign="top"><p>Enumeration</p></td>
      <td valign="top"><p>next，hasNext，nextElement，hasMoreElements</p></td>
    </tr>
  </tbody>
</table>
<p> </p>
<p>8、OGNL中#的使用：</p>
<p>#可以取出堆栈上下文中的存放的对象。</p>
<table align="left" border="1" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td valign="top"><p>名称</p></td>
      <td valign="top"><p>作用</p></td>
      <td valign="top"><p>例子</p></td>
    </tr>
    <tr>
      <td valign="top"><p>parameters</p></td>
      <td valign="top"><p>包含当前HTTP请求参数的Map</p></td>
      <td valign="top"><p>#parameters.id[0]作用相当于</p>
        <p>request.getParameter(&quot;id&quot;)</p></td>
    </tr>
    <tr>
      <td valign="top"><p>request</p></td>
      <td valign="top"><p>包含当前HttpServletRequest的属性（attribute)的Map</p></td>
      <td valign="top"><p>#request.userName相当于</p>
        <p>request.getAttribute(&quot;userName&quot;)</p></td>
    </tr>
    <tr>
      <td valign="top"><p>session</p></td>
      <td valign="top"><p>包含当前HttpSession的属性（attribute）的Map</p></td>
      <td valign="top"><p>#session.userName相当于</p>
        <p>session.getAttribute(&quot;userName&quot;)</p></td>
    </tr>
    <tr>
      <td valign="top"><p>application</p></td>
      <td valign="top"><p>包含当前应用的ServletContext的属性（attribute）的Map</p></td>
      <td valign="top"><p>#application.userName相当于</p>
        <p>application.getAttribute(&quot;userName&quot;)</p></td>
    </tr>
    <tr>
      <td valign="top"><p>attr</p></td>
      <td valign="top"><p>用于按request &gt; session &gt; application顺序访问其属性（attribute）</p></td>
      <td valign="top"><p> </p></td>
    </tr>
  </tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>获取Paraments对象的属性：&lt;s:property value=&quot;#parameters.username&quot;/&gt;</p>
<p>#符号的用途一般有三种。</p>
<p>（1）访问非根对象属性（非ValueStack对象属性），例如#session.msg表达式，由于Struts   2中值栈被视为根对象，所以访问其他非根对象时，需要加#前缀。实际上，#相当于ActionContext.   getContext()。因此，#session.msg表达式相当于ActionContext.getContext().getSession().   getAttribute(&quot;msg&quot;) 。</p>
<p>（2）用于过滤和投影（projecting）集合，如persons.{?#this.age&gt;25}，persons.{?#this.name=='pla1'}.{age}[0]。</p>
<p>（3）用来构造Map，例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。</p>
<p>&nbsp;</p>
<p>9、OGNL中%的使用</p>
<p>用%{}可以取出存在值堆栈中的Action对象，直接调用它的方法。</p>
<p>例如你的Action如果继承了ActionSupport ，那么在页面标签中，用%{getText('key')}的方式可以拿出国际化信息。</p>
<p>&nbsp;</p>
<p>10、OGNL中$的使用：</p>
<p>&ldquo;$&rdquo;有两个主要的用途</p>
<p>A、用于在国际化资源文件中，引用OGNL表达式</p>
<p>B、在Struts 2配置文件中，引用OGNL表达式</p>
<p>&nbsp;</p>
<p>11、值栈：</p>
<p>ValueStack对象。这个对象贯穿整个Action的生命周期（每个Action类的对象实例会拥有一个ValueStack对象）。当   Struts   2接收到一个.action的请求后，会先建立Action类的对象实例，但并不会调用Action方法，而是先将Action类的相应属性放到   ValueStack对象的顶层节点（ValueStack对象相当于一个栈）。</p>
<p>在Action中获得ValueStack对象：ActionContext.getContext().getValueStack()。</p>
<p>值栈的三种使用语法：</p>
<p>（1）Top语法</p>
<p>使用Top获取值栈中的第二个对象:&lt;s:property value=&quot;[1].top.对象&quot;/&gt;</p>
<p>（2）N语法</p>
<p>使用N获取值栈中的第二个对象:&lt;s:property value=&quot;[1].对象&quot;/&gt;</p>
<p>（3） @语法</p>
<p>调用action中的静态方法：&lt;s:property value=&quot;@vs1@静态方法&quot;/&gt;，说明：vs：值栈，1：表示第一个。</p>
</body>
</html>
